package com.huonan.jb.tools.esuse.export.es;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.setting.dialect.Props;
import com.huonan.jb.tools.esuse.config.PropConfig;
import com.huonan.jb.tools.esuse.dto.Configs;
import com.huonan.jb.tools.esuse.dto.EsHitsInfo;
import com.huonan.jb.tools.esuse.export.enums.Env;
import com.huonan.utils.RetryUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @Description TODO
 * @Author lxp
 * @Date 2023/2/6 下午2:33
 * @Version V1.0
 **/
@Slf4j
public class SearchEs {

    private static final String PROD_URL = "http://social-es.mlamp.cn/mz_social";
    private static final String TEST_URL = "http://10.11.110.161:9200";
    // private static String INDEX = "ik_sl_v2_*_ec";
    private static final String scrollTime = "5m";
    private static final String API_KEY = "ApiKey eUVJSzI0c0JjdHA0NjNTbnVVSTU6ejFRXzBmVklRZXUyV2dVNzU1S1hTdw==";

    public static EsHitsInfo preHandler(Env env, boolean isScroll, Props props) {
        Configs configs = PropConfig.getConfigs(env, props);
        String url = prepUrl(env, configs.getIndex(), configs.getScrollId());
        AtomicReference<EsHitsInfo> esHisInfo = new AtomicReference<>(new EsHitsInfo());
        RetryUtil.getInstance().retry(() -> {
            // 在这里编写需要重试的代码
            esHisInfo.set(esSearch(url, configs.getSql(),
                    isScroll, configs.getScrollId()));
            return "success";
        }, 5, 5000);
        return esHisInfo.get();
    }

    private static String prepUrl(Env env, String index, String scrollId) {
        String url = null;
        switch (env) {
            case TEST:
                url = selectUrl(scrollId, TEST_URL, index);
                break;
            case PROD:
                url = selectUrl(scrollId, PROD_URL, index);
                break;
            default:
                break;
        }
        return url;
    }

    private static String selectUrl(String scrollId, String url, String index) {
        if (scrollId != null) {
            return getUrlByScroll(url);
        } else {
            return getUrlFirstScroll(url, index);
        }
    }

    private static String getUrlFirstScroll(String url, String index) {
        return String.format("%s/%s/%s", url, index, "_search?scroll=" + scrollTime);
    }

    private static String getUrlByScroll(String url) {
        return String.format("%s/%s", url, "_search/scroll");
    }

    /**
     * @return java.lang.String
     * @Description 提交
     * @Param [url, sql]
     **/
    private static EsHitsInfo esSearch(String url,
                                       String sql,
                                       boolean isScroll,
                                       String scrollId) {
        EsHitsInfo esHitsInfo = new EsHitsInfo();
        log.info("url:{}", url);
        JSONObject res;
        String result;
        log.info("【查询条件】");
        log.info("url:{}", url);
        if (StringUtils.isNotEmpty(scrollId)) {
            log.info("scrollId:{}", "scrollId");
            result = searchScroid(url, scrollId);
        } else {
            log.info("sql:{}", sql);
            result = SearchWithSql(url, sql);
        }
        res = JSONUtil.parseObj(result);

        scrollId = res.getStr("_scroll_id");
        esHitsInfo.setScrollId(scrollId);
        if (res.getJSONObject("hits") == null) {
            esHitsInfo.setHistTotal(0);
            log.info("查询数据量：{} 条", 0);
            return esHitsInfo;
        }
//        int histTotal = res.getJSONObject("hits").getInt("total");
        int histTotal = res.getJSONObject("hits").getJSONObject("total").getInt("value");
        JSONArray jsonArray = res.getJSONObject("hits").getJSONArray("hits");
//        JSONArray jsonArray = res.getJSONObject("aggregations").getJSONObject("storeID").getJSONArray(
//                "buckets");
        esHitsInfo.setHistTotal(histTotal);
        log.info("导出数据量：{}", jsonArray.size());
        if (jsonArray.size() > 0) {
            esHitsInfo.setHits(jsonArray);
        }
        return esHitsInfo;
    }

    private static String SearchWithSql(String url, String sql) {
        return HttpRequest.post(url)
                .header(Header.AUTHORIZATION, API_KEY)
                .header("Content-Type", "application/json")
                .body(sql)
                .setReadTimeout(1000 * 300)
                .execute()
                .body();
    }

    private static String searchScroid(String url, String scrollId) {
        JSONObject body = new JSONObject();
        body.putOpt("scroll_id", scrollId);
        body.putOpt("scroll", scrollTime);
        return HttpRequest.post(url)
                .header(Header.AUTHORIZATION, API_KEY)
                .header("Content-Type", "application/json")
                .body(body.toString())
                .timeout(1000 * 300)
                .execute()
                .body();
    }
}
